package com.smtx.service.impl;

import com.smtx.service.Service;
import com.smtx.service.ServiceManager;
import com.smtx.service.ServiceManagerException;
import com.smtx.service.ServiceType;
import com.smtx.utils.iterator.ExtIterator;
import com.smtx.utils.iterator.Filter;

import javax.annotation.PostConstruct;
import java.util.*;

/**
 * Created by IntelliJ IDEA.
 * User: repnikov
 * Date: 07.04.11
 * Time: 23:55
 * To change this template use File | Settings | File Templates.
 */
public class ServiceManagerImpl implements ServiceManager {
    protected Map<String, Service> services = new HashMap<String, Service>();

    public ServiceManagerImpl() {}

    public ServiceManagerImpl(Map<String, Service> services) {
        this.services = services;
    }

    @PostConstruct
    public void init() {
        services.clear();
    }

    public void register(String name, Service service) {
        services.put(name, service);
    }
    public void register(Map<String, Service> services) {
        services.putAll(services);
    }
    public Service unregister(String name) {
        return services.remove(name);
    }
    public Set<Service> unregister(Collection<String> names) {
        Set<Service> result = new HashSet<Service>();
        for (String name : names) {
            Service s = unregister(name);
            if (s != null) result.add(s);
        }
        return result;
    }

    public Service getService(String name) throws ServiceManagerException {
        if (services.containsKey(name)) {
            return services.get(name);
        } else {
            throw new ServiceManagerException("Service not found");
        }
    }

    public <X extends Service> X getService(String name, Class<X> clazz) throws ServiceManagerException {
        Service s = getService(name);
        return clazz.cast(s);
    }

    public List<Service> listServices(final ServiceType type) {
        ExtIterator<Service> it = ExtIterator.create(services.values().iterator());
        if (type != null)
            it.addKeepFilter(new Filter() {
                @Override
                public boolean filter(Object o) {
                    return type.equals(((Service) o).getType());
                }
            });
        return it.toList();
    }
    public List<Service> listServices() {
        return listServices(null);
    }
}
